﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Web.UI;
using System.Web.UI.WebControls;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;

namespace Docsbox.Layouts.Docsbox
{
    public partial class associateProject : LayoutsPageBase
    {
        private static string _listId;
        private static string _itemId;
        private static List<int> selectedProjectIds = new List<int>();
        private static string _selectedDealNo = string.Empty;

        protected void Page_Load(object sender, EventArgs e)
        {
            if(!IsPostBack){
                _listId = Request.QueryString["List"];
                _itemId = Request.QueryString["ID"];
                LoadSearchFilters();
                LoadProjectsList(BuildQueryString("All","All",string.Empty));
            }
            lblOverwriteMessage.Visible = false;
            //else
            //{
            //    for (int i = 0; i < listGV.Rows.Count; i++)
            //    {
            //        int projectId = Convert.ToInt32(listGV.DataKeys[i][0]);
            //        CheckBox cb = (CheckBox)listGV.Rows[i].FindControl("checkBoxSelected");
            //        if (cb.Checked)
            //        {
            //            selectedProjectIds.Add(projectId);
            //        }
            //    }

            //    if (selectedProjectIds.Count > 1)
            //    {

            //        Context.Response.Write("<script type='text/javascript'>alert('Select a single project from the list.');</script>");
            //        return;
            //    }
            //    else if(selectedProjectIds.Count == 1)
            //    {
            //        SPWeb site = this.Web;

            //        string status = GetAccountStatus(site, selectedProjectIds[0]);
            //        if (status.Equals(Common.StatusLive, StringComparison.CurrentCultureIgnoreCase) ||
            //            status.Equals(Common.StatusAmendmentRequired, StringComparison.CurrentCultureIgnoreCase))
            //        {
            //            panelReadyforAudit.Visible = true;
            //        }
            //    }
            //}
        }

        private void LoadSearchFilters()
        {
            SPSite siteCollection = this.Site;
            SPWeb web = this.Web;

            SPList financeOffices = web.Lists[Common.ListOffices];
            ddlOffices.Items.Add(new ListItem("All","0"));
            foreach (SPListItem item in financeOffices.Items)
            {
                ddlOffices.Items.Add(new ListItem(item["Title"].ToString(),item.ID.ToString()));
            }


            List<string> statuses = new List<string>();

            SPList statusList = web.Lists[Common.ListAccountStatus];
            ddlStatus.Items.Add(new ListItem("All", "0"));
            foreach (SPListItem item in statusList.Items)
            {
                string status = Common.ConvertFieldToString(item[Common.FieldMTFNo], FieldType.Text);
                //if(!status.Equals(Common.StatusCompleted))
                ddlStatus.Items.Add(new ListItem(status, item.ID.ToString()));
            }
        }

        //load the project list fields
        private void LoadProjectsList(string queryString)
        {
            SPSecurity.RunWithElevatedPrivileges(delegate()
                                                     {
                            SPWeb site = this.Web;

                            SPList list = site.Lists[Common.ListAccounts];

                            SPQuery query = new SPQuery(list.DefaultView);
                            SPListItemCollection result;
                            if (String.IsNullOrEmpty(queryString))
                            {
                                result = list.GetItems(list.DefaultView);
                            }
                            else
                            {
                                query.Query = queryString;

                                query.QueryThrottleMode = SPQueryThrottleOption.Override;
                                query.ViewAttributes += " Scope=\"Recursive\"";
                                query.RowLimit = 12;
                                result = list.GetItems(query);
                            }
                            DataTable database = new DataTable();
                            database.Columns.Add("ItemId");
                            database.Columns.Add("MTFNumber");
                            database.Columns.Add("FirstName");
                            database.Columns.Add("Surname");
                            database.Columns.Add("RegistrationNumber");
                            database.Columns.Add("Office");
                            database.Columns.Add("Status");

                            //only load the first 20 items
                            int max = 15;
                            int count = 0;
                            foreach (SPListItem item in result)
                            {
                                if (count >= max)
                                    break;
                                DataRow row = database.NewRow();
                                row["ItemId"] = item.ID;
                                row["MTFNumber"] = Common.ConvertFieldToString(item[Common.FieldMTFNo], FieldType.Text);
                                row["FirstName"] = Common.ConvertFieldToString(item[Common.FieldFirstName], FieldType.Text);
                                row["Surname"] = Common.ConvertFieldToString(item[Common.FieldSurname], FieldType.Text);
                                row["RegistrationNumber"] = Common.ConvertFieldToString(item[Common.FieldRegNo], FieldType.Text);
                                row["Office"] = Common.ConvertFieldToString(item[Common.FieldFinanceOffice], FieldType.Lookup);
                                row["Status"] = Common.ConvertFieldToString(item[Common.FieldAccountStatus], FieldType.Lookup);
                                database.Rows.Add(row);
                                count++;
                            }

                            listGV.DataSource = database;
                            listGV.DataBind();
                                                     });
        }


        private string BuildQueryString(string office, string status, string keyword)
        {
            //all fielters are default: no keyword, office select all, status select all
            if(string.IsNullOrEmpty(keyword) && office.Equals("All") && status.Equals("All"))
            {
                string query = @"
                                <Where>
                                    <And>
                                        <Or>
                                            <Eq>
                                                <FieldRef Name='{0}' />
                                                <Value Type='Lookup'>{1}</Value>
                                            </Eq>
                                            <Eq>
                                                <FieldRef Name='{0}' />
                                                <Value Type='Lookup'>{2}</Value>
                                            </Eq>
                                        </Or>
                                         <Neq>
                                            <FieldRef Name='ContentType' />
                                            <Value Type='Computed'>Folder</Value>
                                         </Neq>
                                    </And>
                                </Where>
                                   <OrderBy>
                                      <FieldRef Name='{3}' Ascending='False' />
                                   </OrderBy>
                            ";
                return string.Format(query, Common.FieldAccountStatus, Common.StatusLive, Common.StatusAmendmentRequired, Common.FieldAccountStatus);
            }

            //search against keyword to all account
            if (office.Equals("All") && status.Equals("All"))
            {
                string query = @"
                            <Where>
	                            <And>
                                    <Neq>
                                        <FieldRef Name='ContentType' />
                                        <Value Type='Computed'>Folder</Value>
                                     </Neq>
                                    <And>
			                            <Neq>
				                            <FieldRef Name='{2}' />
				                            <Value Type='Lookup'>{0}</Value>
			                            </Neq>
		                                <Or>
			                                <Or>
				                                <Or>
					                                <Or>
						                                <Contains>
							                                <FieldRef Name='{3}'/>
							                                <Value Type='Text'>{1}</Value>
						                                </Contains>
						                                <Contains>
							                                <FieldRef Name='{4}'/>
							                                <Value Type='Text'>{1}</Value>
						                                </Contains>
					                                </Or>
					                                <Contains>
						                                <FieldRef Name='{5}'/>
						                                <Value Type='Text'>{1}</Value>
					                                </Contains>
				                                </Or>
				                                <Contains>
					                                <FieldRef Name='{6}' />
					                                <Value Type='Note'>{1}</Value>
				                                </Contains>
			                                </Or>
			                                <Contains>
				                                <FieldRef Name='{7}' />
				                                <Value Type='Text'>{1}</Value>
			                                </Contains>
		                                </Or>
	                                </And>
                                </And>
                            </Where>";
                return string.Format(query, Common.StatusCompleted, keyword,  Common.FieldAccountStatus, Common.FieldMTFNo, Common.FieldRegNo, Common.FieldSurname, Common.FieldAccountComment, Common.FieldFirstName);
 
            }

            if (string.IsNullOrEmpty(keyword))
            {
                if(office.Equals("All"))
                {
                    string query = @"
                        <Where><And>
			                <Eq>
				                <FieldRef Name='{1}' />
				                <Value Type='Lookup'>{0}</Value>
			                </Eq>
                            <Neq>
                            <FieldRef Name='ContentType' />
                            <Value Type='Computed'>Folder</Value>
                            </Neq>
                        </And></Where>";
                    return string.Format(query, status, Common.FieldAccountStatus);
                }
                if(status.Equals("All"))
                {
                    string query = @"
                        <Where><And>
                            <And>
			                    <Eq>
				                    <FieldRef Name='{1}' />
				                    <Value Type='Lookup'>{0}</Value>
			                    </Eq>
                                <Neq>
                                    <FieldRef Name='{2}' />
                                    <Value Type='Lookup'>{3}</Value>
                                </Neq>
                            </And>
                            <Neq>
                            <FieldRef Name='ContentType' />
                            <Value Type='Computed'>Folder</Value>
                            </Neq>
                        </And></Where>";
                    return string.Format(query, office, Common.FieldFinanceOffice, Common.FieldAccountStatus, Common.StatusCompleted);
                }else
                {
                    string query = @"
                        <Where><And>
		                    <And>
			                    <Eq>
				                    <FieldRef Name='{2}' />
				                    <Value Type='Lookup'>{0}</Value>
			                    </Eq>
			                    <Eq>
				                    <FieldRef Name='{3}' />
				                    <Value Type='Lookup'>{1}</Value>
			                    </Eq>
		                    </And>
                            <Neq>
                            <FieldRef Name='ContentType' />
                            <Value Type='Computed'>Folder</Value>
                            </Neq>
                        </And></Where>";
                    return string.Format(query, office, status,Common.FieldFinanceOffice,Common.FieldAccountStatus);
                }
            } //keyword is not null
            else
            {
                if(status.Equals("All"))
                {
                    //search office and keyword, status is not complete
                    string query = @"
                            <Where><And>
                                 <Neq>
                                    <FieldRef Name='ContentType' />
                                    <Value Type='Computed'>Folder</Value>
                                 </Neq>
	                            <And>
		                            <And>
			                            <Eq>
				                            <FieldRef Name='{3}' />
				                            <Value Type='Lookup'>{0}</Value>
			                            </Eq>
			                            <Neq>
				                            <FieldRef Name='{4}' />
				                            <Value Type='Lookup'>{1}</Value>
			                            </Neq>
		                            </And>
		                            <Or>
			                            <Or>
				                            <Or>
					                            <Or>
						                            <Contains>
							                            <FieldRef Name='{5}'/>
							                            <Value Type='Text'>{2}</Value>
						                            </Contains>
						                            <Contains>
							                            <FieldRef Name='{6}'/>
							                            <Value Type='Text'>{2}</Value>
						                            </Contains>
					                            </Or>
					                            <Contains>
						                            <FieldRef Name='{7}'/>
						                            <Value Type='Text'>{2}</Value>
					                            </Contains>
				                            </Or>
				                            <Contains>
					                            <FieldRef Name='{8}' />
					                            <Value Type='Note'>{2}</Value>
				                            </Contains>
			                            </Or>
			                            <Contains>
				                            <FieldRef Name='{9}' />
				                            <Value Type='Text'>{2}</Value>
			                            </Contains>
		                            </Or>
	                            </And>
                            </And></Where>";
                    return string.Format(query, office, Common.StatusCompleted, keyword, Common.FieldFinanceOffice, Common.FieldAccountStatus, Common.FieldMTFNo, Common.FieldRegNo, Common.FieldSurname, Common.FieldAccountComment, Common.FieldFirstName);

                }
                //office="All", status="Ready"(any status not "All"), and keyword not empty
                if(office.Equals("All"))
                {
                    string query = @"
                            <Where><And>
                                 <Neq>
                                    <FieldRef Name='ContentType' />
                                    <Value Type='Computed'>Folder</Value>
                                 </Neq>
	                            <And>
			                        <Eq>
				                        <FieldRef Name='{2}' />
				                        <Value Type='Lookup'>{0}</Value>
			                        </Eq>
		                            <Or>
			                            <Or>
				                            <Or>
					                            <Or>
						                            <Contains>
							                            <FieldRef Name='{3}'/>
							                            <Value Type='Text'>{1}</Value>
						                            </Contains>
						                            <Contains>
							                            <FieldRef Name='{4}'/>
							                            <Value Type='Text'>{1}</Value>
						                            </Contains>
					                            </Or>
					                            <Contains>
						                            <FieldRef Name='{5}'/>
						                            <Value Type='Text'>{1}</Value>
					                            </Contains>
				                            </Or>
				                            <Contains>
					                            <FieldRef Name='{6}' />
					                            <Value Type='Note'>{1}</Value>
				                            </Contains>
			                            </Or>
			                            <Contains>
				                            <FieldRef Name='{7}' />
				                            <Value Type='Text'>{1}</Value>
			                            </Contains>
		                            </Or>
	                            </And>
                            </And></Where>";
                    return string.Format(query,  status, keyword,  Common.FieldAccountStatus, Common.FieldMTFNo, Common.FieldRegNo, Common.FieldSurname, Common.FieldAccountComment, Common.FieldFirstName);
                }
                else
                {
                     string query = @"
                                <Where><And>
                                     <Neq>
                                        <FieldRef Name='ContentType' />
                                        <Value Type='Computed'>Folder</Value>
                                     </Neq>
	                                <And>
		                                <And>
			                                <Eq>
				                                <FieldRef Name='{3}' />
				                                <Value Type='Lookup'>{0}</Value>
			                                </Eq>
			                                <Eq>
				                                <FieldRef Name='{4}' />
				                                <Value Type='Lookup'>{1}</Value>
			                                </Eq>
		                                </And>
		                                <Or>
			                                <Or>
				                                <Or>
					                                <Or>
						                                <Contains>
							                                <FieldRef Name='{5}'/>
							                                <Value Type='Text'>{2}</Value>
						                                </Contains>
						                                <Contains>
							                                <FieldRef Name='{6}'/>
							                                <Value Type='Text'>{2}</Value>
						                                </Contains>
					                                </Or>
					                                <Contains>
						                                <FieldRef Name='{7}'/>
						                                <Value Type='Text'>{2}</Value>
					                                </Contains>
				                                </Or>
				                                <Contains>
					                                <FieldRef Name='{8}' />
					                                <Value Type='Note'>{2}</Value>
				                                </Contains>
			                                </Or>
			                                <Contains>
				                                <FieldRef Name='{9}' />
				                                <Value Type='Text'>{2}</Value>
			                                </Contains>
		                                </Or>
	                                </And>
                                </And></Where>";
                    return string.Format(query, office, status, keyword,Common.FieldFinanceOffice,Common.FieldAccountStatus,Common.FieldMTFNo,Common.FieldRegNo,Common.FieldSurname,Common.FieldAccountComment,Common.FieldFirstName);
                    
                }
           }
        }

        private List<string> LoadAccountDocuments(string accountDealNo)
        {
            string folderName = accountDealNo.Substring(accountDealNo.Length - 2);
            SPWeb current = this.Web;
            SPList documents = current.Lists[Common.ListDocuments];
            SPQuery query = new SPQuery(documents.DefaultView);
            query.QueryThrottleMode = SPQueryThrottleOption.Override;
            query.Query = GetQueryString(accountDealNo);
            SPFolder folder = documents.RootFolder.SubFolders[folderName];
            query.Folder = folder;
            query.ViewAttributes += " Scope=\"Recursive\"";

            List<string> associatedDocuments = new List<string>();

            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                SPListItemCollection collection = documents.GetItems(query);
                foreach (SPListItem item in collection)
                {
                    associatedDocuments.Add(item.Name);
                }
            });
            return associatedDocuments;
        }
        private string GetQueryString(string filter)
        {
            String query = @"<Where><Eq><FieldRef Name='{1}' /><Value Type='Lookup'>{0}</Value></Eq></Where>";
            return string.Format(query, filter, Common.FieldAccountLookup);
        }
        private bool AssociateDocumentToAccount(SPWeb web,int accountId, bool readyforAudit)
        {
            Guid listId = new Guid(_listId);
            int itemId = Convert.ToInt32(_itemId);

            SPList documents = web.Lists[listId];
            SPListItem document = documents.GetItemById(itemId);

            string documentName = document.Name;

            List<string> associatedDocs = LoadAccountDocuments(_selectedDealNo);

            //a document with the same name already exist, to avoid overwrite, throw exception
            if(associatedDocs.Contains(documentName))
            {
                lblOverwriteMessage.Visible = true;
                return false;
            }
            else
            {
                 if(readyforAudit)
                {

                    SPList list = web.Lists[Common.ListAccounts];
                
                    SPListItem account = list.GetItemById(accountId);

                    account[Common.FieldAccountStatus] = Common.GetLookupStatus(web, Common.StatusReady);

                    web.AllowUnsafeUpdates = true;
                    account.Update();
                    web.AllowUnsafeUpdates = false;
                }

                web.AllowUnsafeUpdates = true;
                document[Common.FieldAccountLookup] = accountId;
                document.Update();
                web.AllowUnsafeUpdates = false;
                return true;
            }
        }

        private string GetAccountStatus(SPWeb web, int accountId)
        {
            SPList list = web.Lists[Common.ListAccounts];
            SPListItem account = list.GetItemById(accountId);
            return Common.ConvertLookupFieldToString(account[Common.FieldAccountStatus]);
            
        }


        public void btnSearch_Cilck(Object sender, EventArgs e)
        {
            lblOverwriteMessage.Visible = false;
            selectedProjectIds = new List<int>();
            Message.Text = "";
            panelReadyforAudit.Visible = false; 
            for (int i = 0; i < listGV.Rows.Count; i++)
            {
                int projectId = Convert.ToInt32(listGV.DataKeys[i][0]);
                CheckBox cb = (CheckBox)listGV.Rows[i].FindControl("checkBoxSelected");
                if (cb.Checked)
                {
                    selectedProjectIds.Add(projectId);
                }
            }

            if (selectedProjectIds.Count > 1)
            {
                Message.Text = "Select a single account from the list.";
                return;
            }

            string office = ddlOffices.SelectedItem.Text;
            string status = ddlStatus.SelectedItem.Text;
            string keyword = txtKeyword.Text.Trim();
            string queryStr = BuildQueryString(office, status, keyword);

            //always reset the readyforaudit checkbox after a new search
            checkBoxReadyforAudit.Checked = false;
            panelReadyforAudit.Visible = false;

            LoadProjectsList(queryStr);
        }

        public void btnSelect_Click(Object sender, EventArgs e)
        {
            Message.Text = "";
            lblOverwriteMessage.Visible = false;

            if (selectedProjectIds.Count == 0)
            {

                Message.Text = "Select an account from the list first.";
                return;
            }
            int projectId = selectedProjectIds[0];
            bool readyforAuditChecked = checkBoxReadyforAudit.Checked;

            SPSite siteCollection = this.Site;
            SPWeb site = this.Web;
            bool success = AssociateDocumentToAccount(site, projectId, readyforAuditChecked);

            if(success)
                ClosePopUp();
        }

        //get the select item, check the selected account status, and enable checkbox for change account status to 'ready for audit'
        public void checkBoxSelected_Changed(Object sender, EventArgs e)
        {
            selectedProjectIds.Clear();
            Message.Text = "";
            lblOverwriteMessage.Visible = false;
            CheckBox cb = (CheckBox)sender;

            if (cb.Checked)
            {
                foreach (GridViewRow gridViewRow in listGV.Rows)
                {
                    CheckBox checkBox = (CheckBox) gridViewRow.FindControl("checkBoxSelected");
                    checkBox.Checked = checkBox == cb;
                }

                GridViewRow row = (GridViewRow)cb.NamingContainer;
                if (row != null)
                {
                    Label id = (Label)row.FindControl("lblItemId");
                    Label dealNo = (Label)row.FindControl("lblDealNo");
                    _selectedDealNo = dealNo.Text;
                    int accountId = Convert.ToInt32(id.Text);
                    selectedProjectIds.Add(accountId);

                    SPWeb site = this.Web;

                    string status = GetAccountStatus(site, accountId);
                    if (status.Equals(Common.StatusLive, StringComparison.CurrentCultureIgnoreCase) ||
                        status.Equals(Common.StatusAmendmentRequired, StringComparison.CurrentCultureIgnoreCase))
                    {
                        panelReadyforAudit.Visible = true;
                    }
                }

            }else
            {
                checkBoxReadyforAudit.Checked = false;
                panelReadyforAudit.Visible = false;
            }
        }

        private void ClosePopUp()
        {
            Context.Response.Write("<Script type='text/javascript'>window.frameElement.commitPopup();</script>");
            Context.Response.Flush();
            Context.Response.End();
        }
    }
}
